// 配置文件类
#pragma once

#include <string>
#include <utility>
#include <vector>

#include "Singleton.h"

namespace raft::utils {
    class Config : public Singleton<Config> {
        friend class Singleton<Config>;

    public:
        // 启动项目
        void start();

        // 获取状态机的 rpc 监听的 ip
        [[nodiscard]] std::string get_state_machine_rpc_ip() const;

        // 获取状态机的 rpc 监听的端口
        [[nodiscard]] int get_state_machine_rpc_port() const;


        // 获取日志名字
        [[nodiscard]] std::string get_log_name() const;

        // 获取心跳超时时间
        [[nodiscard]] int get_heart_beat_timeout() const;

        // 获取应用日志条目的间隔时间
        [[nodiscard]] int get_apply_interval() const;

        // 获取选举超时的最小值
        [[nodiscard]] int get_min_randomized_vote_time() const;

        // 获取选举超时最大值
        [[nodiscard]] int get_max_randomized_vote_time() const;

        // 获取达成共识的超时时间
        [[nodiscard]] int get_consensus_timeout() const;

        [[nodiscard]] int get_max_raft_state() const;

        // 当前节点的监听 ip 地址
        [[nodiscard]] std::string get_raft_core_ip() const;

        // 当前节点的监听端口
        [[nodiscard]] int get_raft_core_port() const;

        // 其他节点的 ip 地址和端口
        [[nodiscard]] std::vector<std::pair<std::string, int>> get_raft_core_peer() const;

    private:
        Config();

        ~Config() override;
        // 加载配置文件
        bool load_config();

        void log_config() const;

        // 日志等级
        bool determine_log_level(const char *);

        // 日志配置信息
        struct log_config_info {
            std::string log_name;
            std::string log_level;
        } log_;

        // state_machine 配置信息
        struct state_machine_info {
            // 状态机 rpc 监听的 ip
            std::string ip;
            // 状态机 rpc 监听的 端口
            int port;
        } state_machine_;

        // raft_core 配置信息，单位是毫秒
        struct raft_config_info {
            // 乘数因子
            int multiplier_factor;
            // 心跳间隔超时时间
            int heart_beat_timeout;
            // 应用日志条目的间隔时间
            int apply_interval;
            // 随机化选举超时的最小和最大值
            int min_randomized_vote_time;
            int max_randomized_vote_time;
            // 达成共识的超时时间
            int consensus_timeout;
            // 节点数据最大值
            int max_raft_state;
            // 当前节点的 ip
            std::string ip;
            // 当前节点端口
            int port;
            // 其他节点
            std::vector<std::pair<std::string, int>> peers;
        } raft_core_;
    };
}// namespace raft::utils
